package org.newlucene.core.index;

import java.io.IOException;

class SegmentsTermPostings implements TermPostings 
{
	protected SegmentReader[] readers;
	protected int[] starts;
	protected Term term;

	protected int base = 0;
	protected int pointer = 0;

	protected SegmentTermPostings[] segTermDocs;
	protected SegmentTermPostings current;              // == segTermDocs[pointer]

	SegmentsTermPostings(SegmentReader[] r, int[] s) 
	{
		readers = r;
		starts = s;

		segTermDocs = new SegmentTermPostings[r.length];
	}

	public int doc() 
	{
		return base + current.doc;
	}
	
	public int freq() 
	{
		return current.freq;
	}

	public void seek(Term term) 
	{
		this.term = term;
		this.base = 0;
		this.pointer = 0;
		this.current = null;
	}

	public boolean nextDoc() throws IOException 
	{
		if (current != null && current.nextDoc()) 
		{
			return true;
		}
		else if (pointer < readers.length) 
		{
			base = starts[pointer];
			current = termPostings(pointer++);
			return nextDoc();
		} 
		else
		{
			return false;
		}
	}

	/** As yet unoptimized implementation. */
	public boolean skipTo(int target) throws IOException 
	{
		do {
			if (!nextDoc())
			{
				return false;
			}
		} 
		while (target > doc());
		
		return true;
	}

	private SegmentTermPostings termPostings(int i) throws IOException 
	{
		if (term == null)
		{
			return null;
		}
		SegmentTermPostings result = segTermDocs[i];
		if (result == null)
		{
			result = segTermDocs[i] = termDocs(readers[i]);
		}
		result.seek(term);
		return result;
	}

	public void close() throws IOException 
	{
		for (int i = 0; i < segTermDocs.length; i++) 
		{
			if (segTermDocs[i] != null)
			{
				segTermDocs[i].close();
			}
		}
	}
	
	protected final SegmentTermPostings termDocs(SegmentReader reader) throws IOException 
	{
		return (SegmentTermPostings)reader.termPostings();
	}

	public final int nextPosition() throws IOException 
	{
		return ((SegmentTermPostings)current).nextPosition();
	}
  
	public final int position() 
	{
		return ((SegmentTermPostings)current).position();
    }  
}